package com.thirdgroup.controller.base;


/**
 * @BelongsProject: login_test
 * @BelongsPackage: com.zys.controller.base
 * @Author: ZYS
 * @CreateTime: 2024-04-28  18:13
 * @Description: TODO
 */

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

import com.thirdgroup.utils.respond.R;


/**
 * 使用说明
 * 1. 继承BaseServlet
 * 2. 前端请求地址后必须加上方法名。例如前端请求调用UserServlet中的login方法，则请求地址为：项目路径/user/login
 * 3. 所继承的servlet中的方法可以有返回值，也可以没有返回值
 * 当方法返回值为String时，返回url格式为："FORWARD:/index.html" 或 "REDIRECT:/index.html"
 * 当方法返回值为其他类型时，如map或者实体类时，返回的数据将被转换为json格式，并返回给前端
 * 若只返回简单字符，建议直接使用respond.getWriter().write(str)方法返回
 * 4.注意，Servlet中的@WebServlet注解，其value访问格式应为"/user/*"，而不是"/user"。
 */

public class BaseServlet extends HttpServlet {
    //转发动作标识
    public static final String FORWARD = "forward:";
    //重定向动作标识
    public static final String REDIRECT = "redirect:";

    //进行方法分发调用
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取访问路径
        String uri = req.getRequestURI();
        //获取访问路径中的方法名
        String methodName = uri.substring(uri.lastIndexOf("/") + 1);
        System.out.println(uri);
        //反射调用方法，并获取方法返回值
        Object result = null;
        try {
            Method declaredMethod = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            declaredMethod.setAccessible(true);
            result = declaredMethod.invoke(this, req, resp);

            //判断返回值是否为空
            if (result != null) {
                //若为字符串，则处理转发和重定向业务
                if (result instanceof String) {
                    String resultStr = (String) result;
                    //判断是转发还是重定向
                    if (resultStr.startsWith(FORWARD)) {
                        //转发
                        req.getRequestDispatcher(resultStr.substring(FORWARD.length())).forward(req, resp);
                    } else if (resultStr.startsWith(REDIRECT)) {
                        //重定向
                        resp.sendRedirect(resultStr.substring(REDIRECT.length()));
                    }
                } else {
                    //处理返回的json数据
                    ObjectMapper mapper = new ObjectMapper();
                    String json = mapper.writeValueAsString(result);
                    //resp.setContentType("application/json;charset=utf-8");
                    resp.getWriter().write(json);
                }
            }
        } catch (Exception e) {
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(R.error(500, "服务器异常"));
            resp.getWriter().write(json);
            e.printStackTrace();
        }

    }
}

